package com.zxjbyte.yiyi.framework.common.util;

import com.zxjbyte.yiyi.framework.common.constant.StringPool;
import com.zxjbyte.yiyi.framework.common.core.html.SafeHtmlFilter;
import lombok.experimental.UtilityClass;

/**
 * HTML工具类
 *
 * @Author zhangxingjia
 * @Date 2023/4/8 11:17
 * @Version: 1.0
 */
@UtilityClass
public class HtmlFilterUtil {

    private static final char[][] X_TEXT = new char[256][];

    static {
        // ascii码值最大的是【0x7f=127】，扩展ascii码值最大的是【0xFF=255】，因为ASCII码使用指定的7位或8位二进制数组合来表示128或256种可能的字符，标准ASCII码也叫基础ASCII码。
        for (int i = 0; i < 256; i++) {
            X_TEXT[i] = new char[] { (char) i };
        }

        // special HTML characters
        X_TEXT['\''] = "&#039;".toCharArray(); // 单引号 ('&apos;' doesn't work - it is not by the w3 specs)
//        X_TEXT['"'] = QUOTE.toCharArray(); // 双引号
        X_TEXT['&'] = StringPool.HTML_AMPERSAND.toCharArray(); // &符
        X_TEXT['<'] = StringPool.HTML_LT.toCharArray(); // 小于号
        X_TEXT['>'] = StringPool.HTML_GT.toCharArray(); // 大于号
        X_TEXT[' '] = StringPool.HTML_NBSP.toCharArray(); // 不断开空格（non-breaking space，缩写nbsp。ASCII值是32：是用键盘输入的空格；ASCII值是160：不间断空格，即 &nbsp，所产生的空格，作用是在页面换行时不被打断）
    }

    /**
     *  转义文本中的HTML字符为安全的字符，以下字符被转义：
     *  (忽略双引号)
     * ' 替换为 &#039; (&apos; doesn't work in HTML4)
     * & 替换为 &amp;
     * < 替换为 &lt;
     * > 替换为 &gt;
     * @param text 被转义的文本
     * @return 转义后的文本
     */
    public String escape(String text) {
        return encode(text);
    }

    /**
     * Encoder
     *
     * @param text 被编码的文本
     * @return 编码后的字符
     */
    private String encode(String text) {
        int len;
        if ((text == null) || ((len = text.length()) == 0)) {
            return StringPool.EMPTY;
        }
        StringBuilder buffer = new StringBuilder(len + (len >> 2));
        char c;
        for (int i = 0; i < len; i++) {
            c = text.charAt(i);
            if (c < 256) {
                buffer.append(X_TEXT[c]);
            } else {
                buffer.append(c);
            }
        }
        return buffer.toString();
    }


    /**
     * 过滤HTML文本，防止XSS攻击
     * 忽略 " 号的转义
     *
     * @param htmlContent HTML内容
     * @return 过滤后的内容
     */
    public String filter(String htmlContent) {
        return new SafeHtmlFilter().filter(htmlContent);
    }
}
